﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Daq;
using Daq.Models;
using Daq.Services;
using Daq.Utils;
using Daq.ViewModels;
using Daq.Views;
using MediaFoundation;
using Microsoft.Extensions.DependencyInjection;
using ScottPlot;
using Serilog;
using SharpDX.Direct3D10;
using SkiaSharp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Diagnostics;
using System.Drawing.Text;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Telerik.Windows.Controls;
using Telerik.Windows.Data;

public enum ChannelType
{
    Voltage,
    Current,
    Resistance,
    Temperature,
    Humidity,
    Pressure,

    //NTC,
    //KThermoCouple,
    //JThermoCouple,
    //TThermoCouple,
    UserDefine,
}

public interface IDaq
{
    Task<ChannelModel[]> GetChannels();
    Task Run(CancellationToken token);
    void Stop1();
    double GetSampleRate();
}

public enum DaqWorkStatus
{
    [Display(Name = "未连接")]
    Disconnected,
    [Display(Name = "搜索中")]
    Searching,
    [Display(Name = "连接中")]
    Connecting,
    [Display(Name = "已连接")]
    Connected,
    [Display(Name = "运行中")]
    Running
}

public class DaqChartSeriesGroup
{
    public string Name { get; set; }
    public ObservableCollection<SeriesViewModel> Series { get; set; } = [];
    public DaqChartSeriesGroup(string name)
    {
        Name = name;
    }
}

public partial class AlertSettings : ObservableObject
{
    [ObservableProperty]
    private bool isEnabled;
    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(SaveCommand))]
    private bool isUpperEnabled;
    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(SaveCommand))]
    private bool isLowerEnabled;
    [ObservableProperty]
    private double upper;
    [ObservableProperty]
    private double lower;
    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(SaveCommand))]
    private string? alias;
    [ObservableProperty]
    private bool alerting;
    public string? Detail => GetDetails(this);

    private static string GetDetails(AlertSettings settings)
    {
        if(settings.IsLowerEnabled && settings.IsUpperEnabled)
        {
            return $" > {settings.Upper} 或 < {settings.Lower}";
        }

        if(!settings.IsLowerEnabled && settings.IsUpperEnabled)
        {
            return $" > {settings.Upper}";
        }

        if(settings.IsLowerEnabled && !settings.IsUpperEnabled)
        {
            return $" < {settings.Lower}";
        }

        return string.Empty;
    }

    [RelayCommand(CanExecute = nameof(CanSave))]
    private void Save()
    {

    }

    private bool CanSave()
    {
        if(!IsUpperEnabled && !IsLowerEnabled)
        {
            return false;
        }
        if(string.IsNullOrWhiteSpace(Alias))
        {
            return false;
        }
        return true;
    }
}

public class DaqMeasureData
{
    public ChannelModel[]? Channels { get; set; }
    public int[]? RawValue { get; set; }
    public DateTime Time { get; set; }
}

struct DataPoint
{
    public DateTime Time;
    public double Value;
}
class PlotBuffer
{
    public string? Name { get; set; }
    public ConcurrentQueue<DataPoint> DataPoints { get; set; } = [];
}

public partial class ChannelDetail : ObservableObject
{
    [ObservableProperty]
    private string? name;
    [ObservableProperty]
    private double max;
    [ObservableProperty]
    private double min;
}

public class ChannelSettings : ObservableObject
{
    public int Index { get; set; }
    private bool status;
    [JsonPropertyName("status")]
    public bool Status
    {
        get { return status; }
        set
        {
            SetProperty(ref status, value);
        }
    }
    private bool isEnabled;
    [JsonPropertyName("isEnabled")]
    public bool IsEnabled
    {
        get { return isEnabled; }
        set
        {
            SetProperty(ref isEnabled, value);
        }
    }

    [JsonIgnore]
    public int GroupIndex { get; set; }

    private bool isVisible;
    [JsonIgnore]
    public bool IsVisible
    {
        get { return isVisible; }
        set
        {
            if (!value) Status = false;
            SetProperty(ref isVisible, value);
        }
    }

    private int digits;
    [JsonPropertyName("digits")]
    public int Digits
    {
        get { return digits; }
        set
        {
            SetProperty(ref digits, value);
        }
    }

    private int physicalType;
    [JsonPropertyName("physicalType")]
    public int PhysicalType
    {
        get { return physicalType; }
        set
        {
            SetProperty(ref physicalType, value);
        }
    }

    private string? unit;
    [JsonPropertyName("unit")]
    public string? Unit
    {
        get { return unit; }
        set
        {
            SetProperty(ref unit, value);
        }
    }

    private DaqColor color = new DaqColor(255, 0, 0);
    [JsonPropertyName("color")]
    public DaqColor Color
    {
        get { return color; }
        set
        {
            SetProperty(ref color, value);
        }
    }

    private double physicalMin;
    [JsonPropertyName("physicalMin")]
    public double PhysicalMin
    {
        get { return physicalMin; }
        set
        {
            SetProperty(ref physicalMin, value);
        }
    }

    private double physicalMax;
    [JsonPropertyName("physicalMax")]
    public double PhysicalMax
    {
        get { return physicalMax; }
        set
        {
            SetProperty(ref physicalMax, value);
        }
    }
    private string? alias;
    [JsonPropertyName("alias")]
    public string? Alias
    {
        get { return alias; }
        set
        {
            SetProperty(ref alias, value);
        }
    }
    private ObservableCollection<TriggerInfo> triggers = [];
    [JsonPropertyName("triggers")]
    public ObservableCollection<TriggerInfo> Triggers
    {
        get { return triggers; }
        set
        {
            SetProperty(ref triggers, value);
        }
    }
}

public class DaqSettings : ObservableObject
{
    private string? version;
    [JsonPropertyName("version")]
    public string? Version
    {
        get { return version; }
        set
        {
            SetProperty(ref version, value);
        }
    }
    private string? sn;
    [JsonPropertyName("sn")]
    public string? SN
    {
        get { return sn; }
        set
        {
            SetProperty(ref sn, value);
        }
    }
    private string? model;
    [JsonPropertyName("model")]
    public string? Model
    {
        get { return model; }
        set
        {
            SetProperty(ref model, value);
        }
    }
    private int channelCount;
    [JsonPropertyName("chCount")]
    public int ChannelCount
    {
        get { return channelCount; }
        set
        {
            SetProperty(ref channelCount, value);
        }
    }

    private ObservableCollection<ChannelSettings>? channels;
    [JsonPropertyName("channels")]
    public ObservableCollection<ChannelSettings>? Channels
    {
        get { return channels; }
        set
        {
            SetProperty(ref channels, value);
        }
    }
    private ObservableCollection<ChannelSettings>? allChannels;
    [JsonIgnore]
    public ObservableCollection<ChannelSettings>? AllChannels
    {
        get { return allChannels; }
        set
        {
            SetProperty(ref allChannels, value);
        }
    }

    private ObservableCollection<ChannelSettings>? selectedChannels;
    [JsonIgnore]
    public ObservableCollection<ChannelSettings>? SelectedChannels
    {
        get { return selectedChannels; }
        set
        {
            SetProperty(ref selectedChannels, value);
        }
    }
    public DaqSettings()
    {
        
    }
}
public class JsonRpcRequest
{
    //public string Jsonrpc { get; set; } = "2.0";
    [JsonPropertyName("method")]
    public object Method { get; set; }
    [JsonPropertyName("params")]
    public object Params { get; set; }
    [JsonPropertyName("id")]
    public int Id { get; set; }
}



public class JsonRpcResponse
{
    //public string Jsonrpc { get; set; }
    [JsonPropertyName("id")]
    public int Id { get; set; }
    [JsonPropertyName("result")]
    public object Result { get; set; }
    [JsonPropertyName("error")]
    public object Error { get; set; }
}

public abstract partial class DaqBase : ObservableRecipient, IRecipient<ValueChangedMessage<ChartTimeDivision>>
{
    public abstract Task<ChannelModel[]?> GetChannelsInfoAsync(CancellationToken token);
    public abstract Task<double> GetSampleRateAsync(CancellationToken token);
    public abstract Task OpenAsync(string address, CancellationToken token);
    public abstract Task CloseAsync(CancellationToken token);
    //public abstract static Task<List<string>> SearchAsync(CancellationToken token);
    public abstract Task<int> FetchAsync(int timeout, CancellationToken token);
    public abstract Task StopAsync(CancellationToken token);
    public abstract Task SendDaqSettings(CancellationToken token);
    public abstract Task SendDaqSettings(DaqInfo daqInfo, CancellationToken token);
    public abstract Task<bool> GetSetDaqSettingsStatus(CancellationToken token);
    public abstract Task<bool> EnsureConnection(CancellationToken token);
    public abstract Task<bool> ModifyAddress(object address, CancellationToken token);
    public abstract Task<DaqInfo?> GetDaqInfo(CancellationToken token);
    public abstract string? Model { get; }
    protected SettingsService? Settings { get; set; }

    private CancellationTokenSource? tokenSource;
    //private ChannelModel[] Channels { get; set; }
    protected DaqMeasureData MeasureData { get; set; } = new();
    public Queue<DaqMeasureData> MeasureDataQueue { get; set; } = new();
    //protected ConcurrentQueue<DaqMeasureData> DatabaseMeasureDataQueue { get; set; } = new();

    [ObservableProperty]
    private ObservableCollection<ChannelModel> displayChannels = [];

    [ObservableProperty]
    private ChartSettingsModel chartSettings = new();

    [ObservableProperty]
    private ObservableCollection<ChannelDetail>? channelDetails;
    [ObservableProperty]
    private long sampleCount;

    [ObservableProperty]
    private ObservableCollection<AlertSettings>? alerts;

    [ObservableProperty]
    private AlertSettings? selectedAlert;

    [ObservableProperty]
    private bool isAlertMute;

    public string SN { get; set; }

    private DaqSettings? daqSettings = new();
    public DaqSettings? DaqSettings
    {
        get => daqSettings;
        set
        {
            SetProperty(ref daqSettings, value);
        }
    }

    private readonly PlotService plotService;
    private readonly ILogger? logger;
    //private Settings? settings;
    public DaqBase(string sn = "")
    {
        SN = sn;
        //this.settings = settings;
        WeakReferenceMessenger.Default.Register<ValueChangedMessage<ChartTimeDivision>>(this);
        Settings = App.Current.Services.GetService<SettingsService>();
        plotService = App.Current.Services.GetService<PlotService>();
        logger = App.Current.Services.GetService<ILogger>();
    }

    public void Receive(ValueChangedMessage<ChartTimeDivision> message)
    {
        Debug.WriteLine(message.Value.GetDisplayName());
    }

    [ObservableProperty]
    //[NotifyCanExecuteChangedFor(nameof(StartCommand))]
    //[NotifyCanExecuteChangedFor(nameof(StopCommand))]
    private DaqWorkStatus status;
    [ObservableProperty]
    private double sampleRate;

    private bool CanStart()
    {
        return Status == DaqWorkStatus.Disconnected;
    }
    private bool CanStop()
    {
        return Status == DaqWorkStatus.Running;
    }

    [ObservableProperty]
    private bool lockYAxes = true;
    public object ChartSync { get; } = new object();
    
    private static string Formatter(DateTime date)
    {
        var secsAgo = (DateTime.Now - date).TotalSeconds;
        return date.ToString("HH:mm:ss");
    }
    private double[] GetSeparators(DateTime start, DateTime end)
    {
        long speratorCount = 5;
        if (start >= end)
        {
            return new double[]
            {
                start.Ticks,
                end.Ticks
            };
        }

        long ticks = (end - start).Ticks;
        long interval = ticks / speratorCount;
        return new double[]
        {
            start.Ticks,
            start.Ticks + interval,
            start.Ticks + interval * 2,
            start.Ticks + interval * 3,
            start.Ticks + interval * 4,
            end.Ticks
        };
    }

    public async Task GetChannelsAsync(CancellationToken token)
    {
        await GetChannelsInfoAsync(token);
        var names = DaqSettings.Channels == null ? [] : DaqSettings.Channels.Select(ch => ch.Alias).ToArray();
        bool hasDuplicates = names.Length != names.Distinct().Count();
        //如名字有重复项，再获取一次。
        if(hasDuplicates)
        {
            logger?.Error("名称有重复项，再次获取通道信息");
            await GetChannelsInfoAsync(token);
        }
        //var chSettings = settings.DaqChannelUserSettings.Instance;
        //if (chSettings == null || chSettings.Channels == null)
        //{
        //    return;
        //}
        //if (DaqSettings.Channels != null)
        //{
        //    for (int i = 0; i < DaqSettings.Channels.Count; i++)
        //    {
        //        DaqSettings.Channels[i].IsVisible = chSettings.Channels.Contains(i);
        //    }
        //}
    }

    public async Task InitialChannels(CancellationToken token)
    {
        await GetChannelsInfoAsync(token);

        //ChartSeriesData.Clear();

        var channels = MeasureData.Channels == null ? [] : MeasureData.Channels.Where(ch => ch.IsEnabled).ToList();

        ////如果DisplayChannels不存在获取到的某个通道，则将这个通道加入到DisplayChannels
        //foreach (var ch in channels)
        //{
        //    if (!DisplayChannels.Any(c => c.Name == ch.Name))
        //    {
        //        DisplayChannels.Add(ch);
        //    }
        //}
        ////如果获取到的通道不存在DisplayChannels的某个通道，则将这个通道移出DisplayChannels
        //if (DisplayChannels.Count > 0)
        //{
        //    for (int i = DisplayChannels.Count - 1; i >= 0; i--)
        //    {
        //        var ch = DisplayChannels[i];
        //        if (!channels.Any(c => c.Name == ch.Name))
        //        {
        //            DisplayChannels.Remove(ch);
        //        }
        //    }
        //}
        foreach (var (displayChannel, ch) in
        from displayChannel in DisplayChannels
        from ch in channels
        where ch.Name == displayChannel.Name
        select (displayChannel, ch))
        {
            ch.IsChartVisible = displayChannel.IsChartVisible;
        }    

        DisplayChannels = [..channels];
        ChannelDetails = [];
        foreach (var ch in DisplayChannels)
        {
            ChannelDetails.Add(new()
            {
                Name = ch.Name,
            });
            ch.Reset();
        }

        //DisplayChannels = new ObservableCollection<ChannelModel>(MeasureData.Channels.Where(ch => ch.IsEnabled).ToList());

        //InitChart(DisplayChannels);
        //foreach (var ch in MeasureData.Channels)
        //{
        //    string groupName = DaqDevice.GetTypeName(ch.Type);

        //    if (!MeasureChannelGroups.Any(t => t.Name == groupName))
        //    {
        //        MeasureChannelGroups.Add(new MeasureDataGroupModel()
        //        {
        //            Name = groupName
        //        });
        //    }
        //}
    }


    private readonly int dataDisplayUpdateIntervalInMillisecond = 500;
    //private DataManagerViewModel? dataManager;
    //private void SaveData(List<string> channelNames, List<int> digits, List<string> units, List<DaqColor> colors)
    //{
    //    List<DaqMeasureData> buffer = [];
    //    DaqMeasureData? data;
    //    buffer.Clear();
    //    dataManager ??= App.Current.Services.GetService(typeof(DataManagerViewModel)) as DataManagerViewModel;
    //    while (DatabaseMeasureDataQueue.TryDequeue(out data))
    //    {
    //        if (data == null) continue;
    //        if (!databaseCreated)
    //        {
    //            dataManager?.CreateDataReport(data.Time, channelNames, digits, units, colors);
    //            databaseCreated = true;
    //        }
    //        buffer.Add(data);
    //        //Debug.WriteLine(data.RawValue.Length);
    //        //Debug.WriteLine(data.RawValue[34]);
    //    }

    //     Debug.WriteLine($"写入数据:{buffer.Count}");
    //    dataManager?.AppendData(buffer);
    //}

    //private bool databaseCreated = false;
    //private async Task DataBaseTask(List<string> channelNames, List<int> digits, List<string> units, List<DaqColor> colors, CancellationToken token)
    //{
    //    Debug.WriteLine("开始数据库任务");
    //    await Task.Run(async () =>
    //    {
    //        DateTime startTime = DateTime.Now;
    //        DateTime now;
    //        List<DaqMeasureData> buffer = [];
    //        TimeSpan timeOutSpan = TimeSpan.FromSeconds(2);
    //        databaseCreated = false;
    //        while (true)
    //        {
    //            now = DateTime.Now;
    //            if (token.IsCancellationRequested)
    //            {
    //                break;
    //            }
    //            if (DatabaseMeasureDataQueue.Count >= 10000 || now - startTime >= timeOutSpan)
    //            {
    //                startTime += timeOutSpan;
    //                SaveData(channelNames, digits, units, colors);
    //            }
    //            await Task.Delay(10);
    //        }
    //        SaveData(channelNames, digits, units, colors);
    //    });
    //    Debug.WriteLine("结束数据库任务");
    //}

    private void PushData(string name, DateTime time, double value)
    {
        var queue = plotQueues.FirstOrDefault(x => x.Name == name);
        if (queue != null)
        {
            queue.DataPoints.Enqueue(new DataPoint
            {
                Time = time,
                Value = value
            });
        }
    }

    //private readonly int maxPlotDataCount = 10000;
    private async Task InitPlot(IEnumerable<ChannelModel> channels)
    {
        await plotService.CommandBuffer.Writer.WriteAsync(new PlotMessage
        {
            Type = PlotMessageType.ClearAllSeries,
        });

        DateTime now = DateTime.Now;
        foreach (var ch in channels)
        {
            plotQueues.Add(new PlotBuffer
            {
                Name = ch.Name,
                DataPoints = []
            });

            await plotService.CommandBuffer.Writer.WriteAsync(new PlotMessage
            {
                ChannelName = ch.Name,
                Type = PlotMessageType.AddSerie,
                Color = ch.Color.ToScottColor(),
                IsVisible = ch.IsChartVisible,
                Unit = ch.Unit
            });
        }
    }

    private List<PlotBuffer> plotQueues = [];
    //private int plotDataCount = 0;

    [ObservableProperty]
    private TimeSpan elapsedTime = TimeSpan.Zero;

    private DateTime firstDateTime = DateTime.Now;

    public async Task ModifyAddress(string address)
    {
        await CloseAsync(CancellationToken.None);
        await OpenAsync(address, CancellationToken.None);
    }


    //private bool isTesting = false;
    [RelayCommand]
    private async Task Test()
    {
        await Task.CompletedTask;
        //bool enabled = false;
        //while(true)
        //{
        //    var daqTask = Start();
        //    List<Task> tasks = [daqTask, Task.Delay(5000)];
        //    await Task.WhenAny(tasks);
        //    if (daqTask.IsCompleted)
        //    {
        //        break;
        //    }
        //    Stop();
        //    await Task.Delay(2000);
        //    DaqSettings.Channels[0].Status = enabled;
        //    DaqSettings.Channels[2].Status = enabled;
        //    DaqSettings.Channels[4].Status = enabled;

        //    enabled = !enabled;
        //    var vm = App.Current.Services.GetService<DeviceConfigurationViewModel>();
        //    await vm.SaveSettings();
        //}
    }


    [DllImport("kernel32.dll")]
    private static extern bool Beep(uint dwFreq, uint dwDuration);
    [DllImport("user32.dll")]
    private static extern bool MessageBeep(uint uType);

    private CancellationTokenSource beepTaskCancellationTokenSource = new();
    private bool beepEnabled;
    private async Task BeepTask()
    {
        try
        {
            while (!beepTaskCancellationTokenSource.IsCancellationRequested)
            {
                if (beepEnabled && !IsAlertMute)
                {
                    MessageBeep(0xFFFFFFFF);
                    await Task.Delay(1000, beepTaskCancellationTokenSource.Token);
                    //Beep(500, 1000);
                }
                await Task.Delay(100, beepTaskCancellationTokenSource.Token);
            }
        }
        catch { }
        beepEnabled = false;
    }

    private void RefreshAlerts(double[] values)
    {
        if (Alerts == null || Alerts.Count == 0)
        {
            return;
        }

        if(DisplayChannels.Count != values.Length)
        {
            Debug.WriteLine("显示数据与采集数据的数量不一致");
            return;
        }
        
        for (int i = 0; i < values.Length; i++)
        {
            var name = DisplayChannels[i].Name;
            var value = values[i];
            foreach(var alert in Alerts)
            {
                if(alert.IsEnabled && alert.Alias == name)
                {
                    if((alert.IsUpperEnabled && value > alert.Upper) || (alert.IsLowerEnabled && value < alert.Lower))
                    {
                        if(!alert.Alerting)
                        {
                            alert.Alerting = true;
                            beepEnabled = true;
                            WeakReferenceMessenger.Default.Send(new DesktopAlertMessage("已触发报警", $"通道[{alert.Alias}] {alert.Detail}"));
                        }
                    }
                }
            }
        }
    }

    private void ClearAlertsState()
    {
        if (Alerts == null)
        {
            return;
        }
        foreach(var alert in Alerts)
        {
            alert.Alerting = false;
        }
    }

    //[RelayCommand(CanExecute = nameof(CanStart))]
    //private async Task Start()
    //{
    //    if(MeasureDataQueue == null)
    //    {
    //        Debug.WriteLine("MeasureDataQueue为空");
    //        return;
    //    }
    //    if (DaqSettings == null || DaqSettings.Channels == null)
    //    {
    //        return;
    //    }

    //    foreach(var ch in DaqSettings.Channels)
    //    {
    //        if(ch.Unit == null || ch.Alias == null)
    //        {
    //            throw new Exception("请检查通道名称和通道单位");
    //        }
    //    }

    //    SampleCount = 0;
    //    ElapsedTime = TimeSpan.Zero;
    //    //Debug.WriteLine("id=" + Environment.CurrentManagedThreadId);
    //    WeakReferenceMessenger.Default.Send(new ValueChangedMessage<ChartTimeDivision>(new()));

    //    logger?.Information("开始运行");
    //    //await Console.Out.WriteLineAsync("运行");
    //    if (Status != DaqWorkStatus.Disconnected) return;

    //    tokenSource = new CancellationTokenSource();
    //    var token = tokenSource.Token;

    //    Status = DaqWorkStatus.Connecting;
    //    //lock (ChartSync)
    //    //{
    //    //    for (int i = 0; i < _values.Count; i++)
    //    //    {
    //    //        var v = _values[i];
    //    //        v.Clear();
    //    //        v = null;
    //    //    }
    //    //    _values.Clear();
    //    //    _values = [];
    //    //}
    //    try
    //    {
    //        Debug.WriteLine("初始化设备");
    //        logger?.Information("初始化设备");
    //        //throw new Exception("地址未设置");
    //        //await OpenAsync(settings.SystemSettings.Instance.Device.Address ?? "", token);
    //        await StopAsync(token);
    //        await Task.Delay(100);
    //        await InitialChannels(token);
    //        logger?.Information($"通道数：{DisplayChannels.Count}");
    //        //await SendDaqSettings(token);
    //    }
    //    catch (Exception ex)
    //    {
    //        string error = $"设备初始化失败：{ex.Message}";
    //        Debug.WriteLine(error);
    //        logger?.Error(error);
    //        try
    //        {
    //            await CloseAsync(token);
    //        }
    //        catch (Exception ex1)
    //        {
    //            Debug.WriteLine(ex1.Message);
    //        }
    //        Status = DaqWorkStatus.Disconnected;
    //        return;
    //    }

    //    Status = DaqWorkStatus.Running;
    //    //int chIndex = 1;
    //    //int refreshCount = 0;

    //    //DatabaseMeasureDataQueue.Clear();
    //    MeasureDataQueue.Clear();

    //    var dataService = App.Current.Services.GetService<DataService>();
    //    var deviceService = App.Current.Services.GetService<DeviceService>();

    //    var settings = App.Current.Services.GetService<SettingsService>();

    //    //var taskDatabase = Task.Factory.StartNew(()=>DataBaseTask(
    //    //    DaqSettings.Channels.Where(ch => ch.Status).Select(ch => ch.Alias).ToList(),
    //    //    DaqSettings.Channels.Where(ch => ch.Status).Select(ch => ch.Digits).ToList(),
    //    //    DaqSettings.Channels.Where(ch => ch.Status).Select(ch => ch.Unit).ToList(),
    //    //    DaqSettings.Channels.Where(ch => ch.Status).Select(ch => ch.Color).ToList(),
    //    //    token), TaskCreationOptions.LongRunning);
    //    ClearAlertsState();
    //    beepTaskCancellationTokenSource = new();
    //    var beepTask = BeepTask();
    //    await InitPlot(DisplayChannels);

    //    //var taskPlot = Task.Factory.StartNew(() => PlotTask(DisplayChannels, token), TaskCreationOptions.LongRunning);
    //    if (DaqSettings == null) return;
    //    var validChannels = DaqSettings.Channels.Where(ch => ch.Status).ToList();
    //    int validChannelsCount = validChannels.Count;
    //    Debug.WriteLine($"有效通道数：{validChannelsCount}");
    //    try
    //    {
    //        // await GetChannelsAsync();
    //        //await DataManagerViewModel.CreateDataReport(DateTime.Now, MeasureData.Channels);

    //        //获取采样率
    //        logger?.Information("获取采样率");
    //        SampleRate = await GetSampleRateAsync(token);
    //        logger?.Information($"获取成功，采样率为{SampleRate}s");
    //        dataService.Start((int)(1 / SampleRate), deviceService.Daqs[0].DaqSettings.Channels.Where(ch => ch.Status)
    //        .Select(ch => new Daq.Services.ChannelInfo { Digits = ch.Digits, Name = ch.Alias, Unit = ch.Unit })
    //        .ToList(), settings.SystemSettings.Instance.DataDirectory, settings.SystemSettings.Instance.Prefix);
    //        DateTime startTime = DateTime.Now;
    //        DateTime updateDisplayStartTime = DateTime.Now;

    //        double[] values = new double[validChannelsCount];
    //        double[] minValues = new double[validChannelsCount];
    //        double[] maxValues = new double[validChannelsCount];
    //        long[] sum = new long[validChannelsCount];
    //        double[] avg = new double[validChannelsCount];
    //        double[] ranges = new double[validChannelsCount];

    //        for (int i = 0; i < validChannelsCount; i++)
    //        {
    //            minValues[i] = double.PositiveInfinity;
    //            maxValues[i] = double.NegativeInfinity;
    //        }

    //        double value;
    //        int digits;
    //        bool firstData = true;
    //        Random _random = new();
    //        logger?.Information("开始采集");
    //        long dataCount = 0;
    //        int groupCount = 1;
    //        double fetchTime = SampleRate * groupCount;
    //        DateTime dataStartTime = DateTime.Now;
    //        bool dataValid;
    //        while (!token.IsCancellationRequested)
    //        {
    //            DateTime now = DateTime.Now;
    //            //fetchTime = SampleRate * groupCount;
    //            //Debug.WriteLine("fetch=" + fetchTime);
    //            dataValid = false;
    //            if (firstData || (now - startTime).TotalSeconds >= fetchTime)
    //            {
    //                startTime = startTime.AddSeconds(fetchTime);

    //                //获取一次数据
    //                groupCount =  await FetchAsync(1000, token);
    //                dataValid = MeasureDataQueue.Count > 0;
    //                if (MeasureDataQueue.Count > 0)
    //                {
    //                    while (MeasureDataQueue.Count > 0)
    //                    {
    //                        //SampleCount++;
    //                        dataCount++;
    //                        var data = MeasureDataQueue.Dequeue();
    //                        if (data.RawValue == null || data.RawValue.Length != validChannels.Count) continue;
    //                        for (int i = 0; i < data.RawValue.Length; i++)
    //                        {
    //                            digits = validChannels[i].Digits;
    //                            value = data.RawValue[i];
    //                            sum[i] += data.RawValue[i];
    //                            avg[i] = Math.Round(sum[i] / dataCount / Math.Pow(10, digits), digits);
    //                            values[i] = Math.Round(value / Math.Pow(10, digits), digits);
    //                            minValues[i] = values[i] < minValues[i] ? values[i] : minValues[i];
    //                            maxValues[i] = values[i] > maxValues[i] ? values[i] : maxValues[i];
    //                            ranges[i] = maxValues[i] - minValues[i];
    //                            //PushData(validChannels[i].Alias, data.Time, values[i]);
    //                        }
    //                        dataService.AppendData((ulong)dataCount, data.RawValue);
    //                        if (firstData)
    //                        {
    //                            firstDateTime = data.Time;
    //                            firstData = false;
    //                        }

    //                        RefreshAlerts(values);
    //                        //Debug.WriteLine(data.RawValue[0]);
    //                        //PushData(data.Time, values);

    //                        //Debug.WriteLine($"len:{data.RawValue.Length}");
    //                        //DatabaseMeasureDataQueue.Enqueue(data);

    //                        int count = 0;
    //                        foreach (var ch in validChannels)
    //                        {
    //                            await plotService.DataBuffer.Writer.WriteAsync(new PlotDataMessage
    //                            {
    //                                ChannelName = ch.Alias,
    //                                Value = values[count],
    //                                Average = avg[count],
    //                                Time = data.Time
    //                            });
    //                            count++;
    //                            //Daq.Plot.DataBuffer.Enqueue(new PlotDataMessage
    //                            //{
    //                            //    ChannelName = ch.Alias,
    //                            //    Value = values[count++],
    //                            //    Time = data.Time
    //                            //});
    //                        }
    //                    }
    //                    //Debug.WriteLine((DateTime.Now - dataStartTime).TotalSeconds + ":" + dataCount);
                        
    //                }
                        
                    
    //            }
    //            if ((now - updateDisplayStartTime).TotalMilliseconds >= dataDisplayUpdateIntervalInMillisecond)
    //            {
    //                updateDisplayStartTime = now;
    //                SampleCount = dataCount;
    //                //ChartDataBuffer? chartDataBuffer = null;

    //                //refreshCount++;

    //                //lock (ChartSync)
    //                //{
    //                //    //DateTime t1 = DateTime.Now;
    //                //    int bufferCount = buffer.Count;
    //                //    Debug.WriteLine(bufferCount);
    //                //    if (bufferCount > 0)
    //                //    {

    //                //        if (bufferCount >= 300 && bufferCount < 1000)
    //                //        {
    //                //            bufferCount = 300;
    //                //        }

    //                //        while (bufferCount-- > 0)
    //                //        {
    //                //            chartDataBuffer = PopData();
    //                //            if (chartDataBuffer != null)
    //                //            {
    //                //                for (int i = 0; i < _values.Count(); i++)
    //                //                {
    //                //                    _values[i].AddLast(new DateTimePoint(chartDataBuffer.Time, chartDataBuffer.Values[i]));
    //                //                    while (_values[i].Count > 10000) _values[i].RemoveFirst();
    //                //                }
    //                //                //Debug.WriteLine("更i性能数据");
    //                //            }
    //                //        }
    //                //        _customAxis.CustomSeparators = GetSeparators(_values[0].First().DateTime, _values[0].Last().DateTime);
    //                //    }
    //                //    //Debug.WriteLine((DateTime.Now - t1).TotalMilliseconds);
    //                //}

    //                for (int i = 0; i < MeasureData.Channels.Length; i++)
    //                {
    //                    MeasureData.Channels[i].Value = values[i];
    //                }
    //                for (int i = 0; i < validChannelsCount; i++)
    //                {
    //                    DisplayChannels[i].Value = values[i];
    //                    DisplayChannels[i].Min = minValues[i];
    //                    DisplayChannels[i].Max = maxValues[i];
    //                    DisplayChannels[i].Average = avg[i];
    //                    DisplayChannels[i].Range = ranges[i];
    //                }


    //                //                  foreach (var group in MeasureChannelGroups)
    //                //{
    //                //	int index = 0;
    //                //	foreach (var ch in group.Channels)
    //                //	{
    //                //		ch.Value = MeasureData.Channels[index++].Value;
    //                //	}
    //                //}
    //            }
    //            if(!firstData)
    //            {
    //                ElapsedTime = DateTime.Now - firstDateTime;
    //            }
    //            if (!dataValid)
    //            {
    //                await Task.Delay(1, token);
    //            }
    //        }
    //    }
    //    catch (OperationCanceledException)
    //    {
    //        Debug.WriteLine("停止采集");
    //        logger?.Information("停止采集");
    //    }
    //    catch (Exception ex)
    //    {
    //        string error = $"异常退出：{ex.Message}";
    //        Debug.WriteLine(error);
    //        logger?.Error(error);
    //    }

    //    try
    //    {
    //        Debug.WriteLine("关闭设备");
    //        logger?.Information("关闭设备");
    //        await StopAsync(CancellationToken.None);
    //        await CloseAsync(CancellationToken.None);
    //    }
    //    catch (Exception ex)
    //    {
    //        string error = $"关闭失败：{ex.Message}";
    //        Debug.WriteLine(error);
    //        logger?.Information(error);
    //    }
    //    tokenSource.Cancel();
    //    beepTaskCancellationTokenSource.Cancel();
    //    dataService?.Stop();
    //    await Task.WhenAll([ beepTask]);
    //    Status = DaqWorkStatus.Disconnected;
    //}

    //[RelayCommand(CanExecute = nameof(CanStop))]
    //private void Stop()
    //{
    //    this.tokenSource?.Cancel();
    //}

    [RelayCommand]
    private void ExportChart(object param)
    {
        if (param == null) return;
        string? extName = param.ToString();
        if (string.IsNullOrWhiteSpace(extName)) return;
        var view = App.Current.Services.GetService<DaqView>();
        view?.OpenSaveImageDialog(extName);
    }

    [RelayCommand]
    private async Task AddAlert()
    {
        //var view = new AlertSettingsView(Channels);
        //var alertSettings = new AlertSettings();
        //view.DataContext = alertSettings;
        //view.Owner = App.Current.MainWindow;
        //view.ShowDialog();
        //if(view.DialogResult == true)
        //{
        //    if(Alerts == null)
        //    {
        //        Alerts = [];
        //    }
        //    Alerts.Add(alertSettings);
        //}
    }

    [RelayCommand]
    private void DeleteAlert()
    {
        if(Alerts == null || SelectedAlert == null)
        {
            return;
        }

        RadWindow.Confirm(new DialogParameters()
        {
            Header = "确认删除",
            Content = $"确定删除[{SelectedAlert.Alias}]的报警吗？",
            Closed = OnConfirmWindowClosed
        });
        if(deleteConfirmResult)
        {
            Alerts.Remove(SelectedAlert);
        }
    }

    private bool deleteConfirmResult;
    private void OnConfirmWindowClosed(object sender, WindowClosedEventArgs e)
    {
        deleteConfirmResult = e.DialogResult == true;
    }
}

public class ChartData
{
    public bool IsEnabled { get; set; }
    public double Value { get; set; }
    public DateTime Category { get; set; }
}

public class ChartDataGroup
{
    public string Name { get; set; } = "";
    public string Unit { get; set; } = "";
    public ObservableCollection<ChartData> Channels { get; set; } = [];
}

public class DataItem
{
    public string Category { get; set; }

    public double Value { get; set; }
}

public class SeriesViewModel
{
    public string SeriesType { get; set; }

    public ObservableCollection<DataItem> Items { get; set; } = [];

}

public class DaqDevice
{
    List<ChannelModel> Channels { get; set; } = [];
    public static string GetDefaultUnit(ChannelType type)
    {
        return type switch
        {
            ChannelType.Voltage => "V",
            ChannelType.Current => "A",
            ChannelType.Temperature => "°C",
            ChannelType.Resistance => "Ω",
            ChannelType.Humidity => "%",
            ChannelType.Pressure => "kPa",
            ChannelType.UserDefine => "",
            _ => "",
        };
    }

    public static string GetTypeName(ChannelType type)
    {
        return type switch
        {
            ChannelType.Voltage => "电压",
            ChannelType.Current => "电流",
            ChannelType.Temperature => "温度",
            ChannelType.Resistance => "电阻",
            ChannelType.Humidity => "湿度",
            ChannelType.Pressure => "压力",
            ChannelType.UserDefine => "",
            _ => "",
        };
    }
    public static string GetTypeName(string unit)
    {
        var type = GetChannelType(unit);
        return type switch
        {
            ChannelType.Voltage => "电压",
            ChannelType.Current => "电流",
            ChannelType.Temperature => "温度",
            ChannelType.Resistance => "电阻",
            ChannelType.Humidity => "湿度",
            ChannelType.Pressure => "压力",
            ChannelType.UserDefine => "",
            _ => "",
        };
    }

    public static string[] GetUnits(ChannelType type)
    {
        return type switch
        {
            ChannelType.Voltage => ["nV", "uV", "mV", "V", "kV"],
            ChannelType.Current => ["nA", "uA", "mA", "A"],
            ChannelType.Resistance => ["uΩ", "mΩ", "Ω", "kΩ", "MΩ", "GΩ"],
            ChannelType.Temperature => ["°C"],
            ChannelType.Humidity => ["%"],
            ChannelType.Pressure => ["kPa", "MPa", "bar", "psi"],
            _ => [],
        };
    }

    public static ChannelType GetChannelType(string? unit)
    {
        return unit switch
        {
            "nV" => ChannelType.Voltage,
            "uV" => ChannelType.Voltage,
            "mV" => ChannelType.Voltage,
            "V" => ChannelType.Voltage,
            "kV" => ChannelType.Voltage,

            "nA" => ChannelType.Current,
            "uA" => ChannelType.Current,
            "mA" => ChannelType.Current,
            "A" => ChannelType.Current,

            "uΩ" => ChannelType.Resistance,
            "mΩ" => ChannelType.Resistance,
            "Ω" => ChannelType.Resistance,
            "kΩ" => ChannelType.Resistance,
            "MΩ" => ChannelType.Resistance,
            "GΩ" => ChannelType.Resistance,

            "°C" => ChannelType.Temperature,
            "℃" => ChannelType.Temperature,

            "%" => ChannelType.Humidity,

            "kPa" => ChannelType.Pressure,
            "MPa" => ChannelType.Pressure,
            "bar" => ChannelType.Pressure,
            "psi" => ChannelType.Pressure,

            _ => ChannelType.Voltage
        };
    }
}
